package com.atlin.project.fastDev;

import cn.hutool.core.io.FileUtil;
import com.atlin.project.model.domain.cds.ClientCode;
import com.atlin.project.model.domain.cds.ClientFile;
import com.atlin.project.model.domain.cds.FileMetadata;
import com.atlin.project.model.domain.task.TaskTags;

import java.io.File;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.atlin.project.fastDev.TemplateConstants.targetPath;
import static com.atlin.project.fastDev.TemplateConstants.templateParentPath;

/**
 * @author atlin
 * @description 快速开发 crud
 * @createDate 2024/12/4 18:05
 */
public class DevMain {

    /**
     * 原始数据路径 实体类
     */
    private static final String sourcePath = "src/main/java/com/atlin/project/model/domain/cds";

    /**
     * 模版文件 -- 用于校验
     */
    private static final String[] defaultTemplate = new String[]{"TempTemplateController.java", "TempTemplateAddRequest.java", "TempTemplateEditRequest.java", "TempTemplateQueryRequest.java", "TempTemplateUpdateRequest.java",
            "TempTemplateVO.java", "TempTemplateServiceImpl.java", "TempTemplateService.java"};
    

    /**
     * 需要生成crud的实体类
     * <p>TestFastDev.class</p>
     */
    private static final Class[] sourceClass = new Class[]{ClientCode.class, ClientFile.class, FileMetadata.class};


    public static void main(String[] args) {
        run();
    }

    public static void run() {
        preCheck();
        String parentPath = System.getProperty("user.dir");

        for (Class clazz : sourceClass) {
            String className = clazz.getSimpleName();
            System.out.println("----> " + className);

            String content = FileUtil.readUtf8String(parentPath + '/' + sourcePath + '/' + className + ".java");
            String domainField = getDomainField(content);

            gen(parentPath, className, domainField);

        }

        System.out.println(parentPath);

    }

    private static void gen(String parentPath, String className, String domainField) {
        String templatePath = parentPath + '/' + templateParentPath;
        String target = parentPath + '/' + targetPath;

        String firstLower = className.substring(0, 1).toLowerCase();
        String className_L = firstLower + className.substring(1);

        genVO(templatePath, className, className_L, domainField, target);
        genDto(templatePath, className, className_L, domainField, target);
        genService(templatePath, className, className_L, target);
        genServiceImpl(templatePath, className, className_L, target);
        genController(templatePath, className, className_L, target);
    }

    private static void genController(String templatePath, String className, String className_L, String targetPath) {
        String content = FileUtil.readUtf8String(templatePath + "/controller/TempTemplateController.java");

        String res = content.replaceAll("className_C", className)
                .replaceAll("className_L", className_L);

        String filePath = targetPath + "/controller/" + className + "Controller.java";
        File file = FileUtil.writeString(res, filePath, "UTF-8");
        if (file.exists() && file.isFile()) {
            System.out.println("    ----> " + file.getName());
        }
    }

    private static void genService(String templatePath, String className, String className_L, String targetPath) {
        String content = FileUtil.readUtf8String(templatePath + "/service/TempTemplateService.java");

        String res = content.replaceAll("className_C", className)
                .replaceAll("className_L", className_L);

        String filePath = targetPath + "/service/" + className + "Service.java";
        File file = FileUtil.writeString(res, filePath, "UTF-8");
        if (file.exists() && file.isFile()) {
            System.out.println("    ----> " + file.getName());
        }
    }

    private static void genServiceImpl(String templatePath, String className, String className_L, String targetPath) {
        String content = FileUtil.readUtf8String(templatePath + "/service/impl/TempTemplateServiceImpl.java");

        String res = content.replaceAll("className_C", className)
                .replaceAll("className_L", className_L);

        String filePath = targetPath + "/service/impl/" + className + "ServiceImpl.java";
        File file = FileUtil.writeString(res, filePath, "UTF-8");
        if (file.exists() && file.isFile()) {
            System.out.println("    ----> " + file.getName());
        }
    }

    private static void genVO(String templatePath, String className, String className_L, String domainField, String targetPath) {
        String content = FileUtil.readUtf8String(templatePath + "/model/vo/TempTemplateVO.java");

        String res = replace(content, className, className_L, domainField);


        String filePath = targetPath + "/model/vo/" + className + "VO.java";

        File file = FileUtil.writeString(res, filePath, "UTF-8");
        if (file.exists() && file.isFile()) {
            System.out.println("    ----> " + file.getName());
        }
    }

    private static void genDto(String templatePath, String className, String className_L, String domainField, String targetPath) {
        String path = templatePath + "/model/dto/tempTemplate/";

        File dir = new File(path);
        // 检查路径是否存在且是一个目录
        if (dir.exists() && dir.isDirectory()) {
            File[] files = dir.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isFile()) {
                        String fileName = file.getName().replace("TempTemplate", className);
                        String content = FileUtil.readUtf8String(file);
                        String res = replace(content, className, className_L, domainField);
                        String filePath = targetPath + "/model/dto/" + className_L + '/' + fileName;

                        File resFile = FileUtil.writeString(res, filePath, "UTF-8");
                        if (resFile.exists() && resFile.isFile()) {
                            System.out.println("    ----> " + resFile.getName());
                        }
                    }
                }
            }
        } else {
            System.out.println("dto path is not a directory or does not exist.");
        }
    }

    private static String replace(String content, String className, String className_L, String domainField) {
        return content.replaceAll("className_C", className)
                .replaceAll("className_L", className_L)
                .replaceAll("request_content", domainField);
    }


    private static String getDomainField(String input) {
        String res = "";
        String regex = "\\{([^}]*)\\}";
        Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
        Matcher matcher = pattern.matcher(input);

        // 提取并输出匹配的内容
        if (matcher.find()) {
            String content = matcher.group(1);
            // 去除 @TableId 和 @TableField(exist = false) 及之后的内容
            content = content.replaceAll("@TableId\\(.*?\\)", "")
                    .replaceAll("@TableField\\(exist = false\\).*", "")
                    .replaceAll("private static final long serialVersionUID = 1L;", "")
                    // 去除末尾的所有空行
                    .replaceAll("\\s+$", "");
            res = content;
        }
        return res;
    }
    

    /**
     * 校验模版文件是否存在
     */
    private static void preCheck() {
        String parentPath = System.getProperty("user.dir");
        // 检查模版文件是否存在
        File dir = new File(parentPath + "/" + templateParentPath);
        LinkedList<String> templateNameList = new LinkedList<>(Arrays.asList(defaultTemplate));

        if (dir.exists() && dir.isDirectory()) {
            List<File> fileList = FileUtil.loopFiles(dir);
            for (File file : fileList) {
                templateNameList.remove(file.getName());
            }
        } else {
            throw new RuntimeException(dir.getPath() + " 路径不是目录或不存在。");
        }

        if (!templateNameList.isEmpty()) {
            try {
                // 生成模版文件
                GenerateTemplate.doGenerate();
            } catch (Exception e) {
                throw new RuntimeException("模版文件缺失 --> " + templateNameList);
            }
        }
    }
}
